<?php

/**
 * Maikuro Framework
 *
 * LICENSE:
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * The license is bundled with this package in the file LICENSE.txt.
 * You may also obtain a copy of the License at this URL:
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @copyright  Copyright (c) 2010, Jonathan Hedrén
 * @author     Jonathan Hedrén <jonathan.hedren@gmail.com>
 * @license    http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */


class Validators
{
    const VALIDATOR_DATE      = 'date';
    const VALIDATOR_EMAIL     = 'email';
    const VALIDATOR_ENDS_WITH = 'endsWith';
    const VALIDATOR_INT       = 'int';
    const VALIDATOR_IP        = 'ip';
    const VALIDATOR_MAX_SIZE  = 'maxSize';
    const VALIDATOR_MIN_SIZE  = 'minSize';
    const VALIDATOR_REGEXP    = 'regexp';
    const VALIDATOR_REQUIRED  = 'required';
    const VALIDATOR_URL       = 'url';

    const MSG_SHORTER_THAN_MINSIZE = 'is too short.';
    const MSG_REQUIRED             = 'is required.';
    const MSG_LARGER_THAN_MAXSIZE  = 'is too large.';
    const MSG_NOT_AN_EMAIL_ADDRESS = 'is not a valid email address.';
    const MSG_NOT_AN_URL           = 'is not a valid URL.';
    const MSG_NOT_AN_IP            = 'is not a valid IP address.';
    const MSG_NOT_AN_INTEGER       = 'is not an integer.';
    const MSG_REGEXP_NOT_MATCHED   = 'does not match.';
    const MSG_NOT_NUMERIC          = 'is not numeric.';
    const MSG_NOT_VALID_DATE       = 'is not a valid date.';

    /**
     * @var
     */
    protected static $messages = array();

    /**
     * Date validator.
     *
     * @param mixed $value
     * @param string $message
     * @return boolean
     */
    public static function date($value, $message = null)
    {
        //FIXME: regexp instead of is_numeric as , is not allowed as separator...
        if (!is_numeric($value)) {
            self::$messages[] = ($message !== null) ? $message : self::MSG_NOT_NUMERIC;
            return false;
        }
        return true;

    }

    /**
     * Email address validator.
     *
     * @param string $value
     * @param string $message
     * @return boolean
     */
    public static function email($value, $message = null)
    {
        if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
            self::$messages[] = ($message !== null) ? $message : self::MSG_NOT_AN_EMAIL_ADDRESS;
            return false;
        }
        return true;
    }

    /**
     * Tests if $string ends with $test.
     *
     * @return boolean
     * @param string $string
     * @param string $test
     */
    public static function endsWith($string, $test) {
        $stringLength = strlen($string);
        $testLength = strlen($test);
        if ($testLength > $stringLength) {
            return false;
        }
        return substr_compare($string, $test, -$testLength) === 0;
    }

    /**
     * Returns any validation messages after clearing the self::$messages array.
     *
     * @return array
     */
    public static function getMessages()
    {
        $messages = self::$messages;
        self::$messages = array();
        return count($messages) ? $messages : null;
    }

    /**
     * Integer validator.
     *
     * @param mixed $value
     * @param string $message
     * @return boolean
     */
    public static function int($value, $message = null)
    {
        if (!filter_var($value, FILTER_VALIDATE_INT)) {
            self::$messages[] = ($message !== null) ? $message :  self::MSG_NOT_AN_INTEGER;
            return false;
        }
        return true;
    }

    /**
     * IP address validator.
     *
     * @param mixed $value
     * @param string $message
     * @return boolean
     */
    public static function ip($value, $message = null)
    {
        if (!filter_var($value, FILTER_VALIDATE_IP)) {
            self::$messages[] = ($message !== null) ? $message :  self::MSG_NOT_AN_IP;
            return false;
        }
        return true;
    }

    /**
     * Max size validator.
     *
     * @param mixed $value
     * @param integer $params
     * @param string $message
     * @return boolean
     */
    public static function maxSize($value, $maxSize, $message = null)
    {
        if (strlen($value) > (int) $maxSize) {
            self::$messages[] = ($message !== null) ? $message : self::MSG_LARGER_THAN_MAXSIZE;
        }
        return true;
    }

    /**
     * Minimum size validator.
     *
     * @param mixed $value
     * @param integer $minSize
     * @param string $message
     * @return boolean
     */
    public static function minSize($value, $minSize, $message = null)
    {
        if (strlen($value) < (int) $minSize) {
            self::$messages[] = ($message !== null) ? $message : self::MSG_SHORTER_THAN_MINSIZE;
            return false;
        }
        return true;
    }

    /**
     * Numeric validator.
     *
     * @param mixed $value
     * @param string $message
     * @return boolean
     */
    public static function numeric($value, $message = null)
    {
        // TODO
    }

    /**
     * Required validator.
     *
     * @param mixed $value
     * @param string $message
     * @return boolean
     */
    public static function required($value, $message = null)
    {
        if (strlen($value) === 0) {
            self::$messages[] = ($message !== null) ? $message : self::MSG_REQUIRED;
            return false;
        }
        return true;
    }

    /**
     * URL validator.
     *
     * @param string $value
     * @param string $message
     * @return boolean
     */
    public static function url($value, $message = null)
    {
        if (!filter_var($value, FILTER_VALIDATE_URL)) {
            self::$messages[] = ($message !== null) ? $message : self::MSG_NOT_AN_URL;
            return false;
        }
        return true;
    }

    /**
     * Regexp validator.
     *
     * @param string $value
     * @param string $regexp
     * @param string $message
     * @return boolean
     */
    public static function regexp($value, $regexp, $message = null)
    {
        if (!filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => $regexp)))) {
            self::$messages[] = ($message !== null) ? $message : self::MSG_REGEXP_NOT_MATCHED;
            return false;
        }
        return true;
    }
}
